package com.jack.lib.ui.widget

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources.NotFoundException
import android.content.res.TypedArray
import android.graphics.Rect
import android.graphics.Typeface
import android.text.*
import android.util.AttributeSet
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import androidx.annotation.StringRes
import androidx.appcompat.widget.AppCompatEditText
import com.jack.lib.ui.R
import com.jack.lib.ui.filter.AmountInputFilter

/**
 * 作者: jack(黄冲)
 * 邮箱: 907755845@qq.com
 * create on 2018/11/20 14:16
 */
@SuppressLint("AppCompatCustomView")
class JEditText @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : AppCompatEditText(context, attrs), OnGlobalLayoutListener {

    var onChangedAfterTextBlock: ((String) -> Unit) = { }
    var onKeyboardStatusBlock: ((isShow: Boolean) -> Unit) = { }
        set(value) {
            field = value
            viewTreeObserver.addOnGlobalLayoutListener(this)
        }
    private var isSoftKeyboardOpened = false
    private var mCursorEnd = false
    private var mJInputType = 0
    private var mTypeface: Typeface? = null
    private var mHintTypeface: Typeface? = null

    private object TextStyle {
        /* 粗体 */
        const val BOLD = 1

        /* 斜体 */
        const val ITALIC = 2

        /* 常规 */
        const val NORMAL = 3
    }

    object JInputType {
        //金额到分
        const val MONEY = 1
        const val MONEY_INT = 2
    }

    init {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.JEditText)
        parseAttr(typedArray)
        typedArray.recycle()
    }
    private fun parseAttr(typedArray: TypedArray) {
        mCursorEnd = typedArray.getBoolean(R.styleable.JEditText_JCursorEnd, false)
        val textStyle = typedArray.getInt(R.styleable.JEditText_JHintTextStyle, 0)
        mJInputType = typedArray.getInt(R.styleable.JEditText_JInputType, 0)
        if (textStyle == TextStyle.BOLD) {
            mHintTypeface = Typeface.defaultFromStyle(Typeface.BOLD)
        } else if (textStyle == TextStyle.ITALIC) {
            mHintTypeface = Typeface.defaultFromStyle(Typeface.ITALIC)
        } else if (textStyle == TextStyle.NORMAL) {
            mHintTypeface = Typeface.defaultFromStyle(Typeface.NORMAL)
        }
        mTypeface = typeface
        if (textStyle != 0) {
            paint.typeface = mHintTypeface
        }
        if (mJInputType == JInputType.MONEY) {
            inputType =
                InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL or InputType.TYPE_NUMBER_VARIATION_NORMAL
            filters = arrayOf<InputFilter>(AmountInputFilter())
        } else if (mJInputType == JInputType.MONEY_INT) {
            inputType = InputType.TYPE_CLASS_NUMBER
            filters = arrayOf<InputFilter>(AmountInputFilter())
        }
        setOnChangedAfterTextListener()
    }

    override fun setText(text: CharSequence?, type: BufferType) {
        super.setText(text, type)
        if (TextUtils.isEmpty(text) && mHintTypeface != null) {
            paint.typeface = mHintTypeface
        }
    }

    val string: String
        get() = text.toString()

    fun text(text: CharSequence?) {
        super.setText(text)
    }

    fun text(@StringRes resid: Int) {
        try {
            super.setText(resid)
        } catch (e: NotFoundException) {
            super.setText(resid.toString())
        }
    }

    fun text(): String {
        return text.toString()
    }

    private fun setOnChangedAfterTextListener() {
        addTextChangedListener(object : JTextWatcher() {
            override fun afterTextChanged(s: Editable) {
                if (s.toString().isEmpty()) {
                    paint.typeface = mHintTypeface
                } else {
                    paint.typeface = mTypeface
                }
                onChangedAfterTextBlock.invoke(s.toString())
            }
        })
    }

    override fun onSelectionChanged(selStart: Int, selEnd: Int) {
        super.onSelectionChanged(selStart, selEnd)
        if (mCursorEnd && selStart == selEnd) {
            if (text?.length == 0) {
                setSelection(0)
            } else {
                setSelection(text?.length?: 0)
            }
        }
    }

    abstract class JTextWatcher : TextWatcher {
        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
        override fun afterTextChanged(s: Editable) {}
    }

    override fun onGlobalLayout() {
        val r = Rect()
        getWindowVisibleDisplayFrame(r)
        val heightDiff = rootView.height - (r.bottom - r.top)
        if (!isSoftKeyboardOpened && heightDiff > 100) {
            isSoftKeyboardOpened = true
            onKeyboardStatusBlock.invoke(true)
        } else if (isSoftKeyboardOpened && heightDiff < 100) {
            isSoftKeyboardOpened = false
            onKeyboardStatusBlock.invoke(false)
        }
    }
}